package com.rightsidetech.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.PageRequest;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.StringUtil;
import com.rightsidetech.system.dtos.request.SysAgentResourceRoleResp;
import com.rightsidetech.system.dtos.request.SysRoleAddReq;
import com.rightsidetech.system.dtos.request.SysRoleUpdateReq;
import com.rightsidetech.system.dtos.response.SysRoleDetailResp;
import com.rightsidetech.system.dtos.response.SysRoleResp;
import com.rightsidetech.system.entity.*;
import com.rightsidetech.system.mapper.*;
import com.rightsidetech.system.service.SysAgentRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: yhr
 * @Date: 2021-10-29 11:29
 */
@Slf4j
@Service("sysAgentRoleServiceImpl")
public class SysAgentRoleServiceImpl implements SysAgentRoleService {
    @Resource
    private SysAgentLoginInfoMapper sysAgentLoginInfoMapper;
    @Resource
    private SysAgentRoleMapper sysAgentRoleMapper;
    @Resource
    private SysAgentResourceMapper sysAgentResourceMapper;
    @Resource
    private SysAgentRoleAccountMapper sysAgentRoleAccountMapper;
    @Resource
    private SysAgentRoleResourceMapper sysAgentRoleResourceMapper;

    @Override
    public ResponseData<PageInfo<SysRoleResp>> page(PageRequest req, Long loginInfoId, Long isAgent) throws Exception {
        List<SysRoleResp> list = null;
        if (isAgent == 1){
            PageHelper.startPage(req.getPageNo(), req.getPageSize());
            list = sysAgentRoleMapper.selectAgentList(req);
        }else {
            SysAgentLoginInfo info = sysAgentLoginInfoMapper.selectAgentId(loginInfoId);
            if (StringUtils.isEmpty(info)) {
                return ResponseData.fail("未查询到此帐号代理商");
            }
            PageHelper.startPage(req.getPageNo(), req.getPageSize());
            list = sysAgentRoleMapper.selectList(req, info.getAgentInfoId());
        }
        return ResponseData.success(new PageInfo<>(list));
    }

    @Override
    public ResponseData saveSysRole(SysRoleAddReq sysRoleAddReq, Long loginInfoId, String type) throws Exception {
        if ("agent".equals(type)){
            List<Long> longs = sysAgentRoleResourceMapper.selectByLoginId(loginInfoId);
            for (Long lo:sysRoleAddReq.getResourceList()) {
                if (!longs.contains(lo)){
                    return ResponseData.fail("所选权限超出此账号最大权限");
                }
            }
        }
        Long agentInfoId = 0L;
        SysAgentRole sysAgentRole = new SysAgentRole();
        sysAgentRole.setName(sysRoleAddReq.getName());
        sysAgentRole.setRoleDetail(sysRoleAddReq.getRoleDetail());
        sysAgentRole.setCreaterId(loginInfoId);
        sysAgentRole.setCreatedAt(new Date());
        //如果是admin创建 代理商id为0，创建者id为总平台帐号id
        if ("admin".equals(type)){
            sysAgentRole.setAgentInfoId((long) 0);
        }else if ("agent".equals(type)){
            SysAgentLoginInfo info = sysAgentLoginInfoMapper.selectAgentId(loginInfoId);
            if (StringUtils.isEmpty(info)) {
                return ResponseData.fail("未查询到此帐号代理商");
            }
            agentInfoId = info.getAgentInfoId();
            sysAgentRole.setAgentInfoId(info.getAgentInfoId());
        }
        //判断角色名称是否重复
        SysAgentRole agentRole = sysAgentRoleMapper.selectByName(sysAgentRole.getName(), agentInfoId);
        if (null != agentRole) {
            return ResponseData.fail("角色名称重复");
        }
        sysAgentRoleMapper.insertSelective(sysAgentRole);
        //添加权限
        roleAddResource(sysAgentRole.getId(), sysRoleAddReq.getResourceList());
        return ResponseData.success();
    }

    private void roleAddResource(Long roleId, List<Long> resourceList) {
        //添加权限
        List<SysAgentRoleResource> list = new ArrayList<>();
        resourceList.forEach(item -> {
            SysAgentRoleResource sysRoleResource = new SysAgentRoleResource();
            sysRoleResource.setRoleId(roleId);
            sysRoleResource.setResourceId(item);
            sysRoleResource.setCreatedAt(new Date());
            list.add(sysRoleResource);
        });
        sysAgentRoleResourceMapper.insertRoleResouceList(list);
    }

    @Override
    public ResponseData updateSysRole(SysRoleUpdateReq sysRoleUpdateReq, Long loginInfoId, String type) throws Exception {
        Long agentInfoId = 0L;
        if ("agent".equals(type)){
            SysAgentLoginInfo loginInfo = sysAgentLoginInfoMapper.selectByPrimaryKey(loginInfoId);
            if (StringUtils.isEmpty(loginInfo)) {
                return ResponseData.fail("未查询到此帐号");
            }
            List<Long> resps = sysAgentRoleMapper.selectLongList(loginInfo.getAgentInfoId());
            if (ObjectUtils.isEmpty(resps) && !resps.contains(sysRoleUpdateReq.getId())){
                return ResponseData.fail("未找到此角色");
            }
            if ("agent".equals(type)) {
                agentInfoId = loginInfo.getAgentInfoId();
            }
        }

        SysAgentRole sysRole1 = sysAgentRoleMapper.selectByName(sysRoleUpdateReq.getName(), agentInfoId);
        if (null != sysRole1 && !sysRoleUpdateReq.getId().equals(sysRole1.getId())) {
            return ResponseData.fail("角色名称重复");
        }

        //判断角色是否已经删除
        SysAgentRole sysRole2 = sysAgentRoleMapper.selectByPrimaryKey(sysRoleUpdateReq.getId());
        if (ObjectUtils.isEmpty(sysRole2)) {
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        SysAgentRole sysRole = new SysAgentRole();
        sysRole.setId(sysRoleUpdateReq.getId());
        sysRole.setName(sysRoleUpdateReq.getName());
        sysRole.setRoleDetail(sysRoleUpdateReq.getRoleDetail());
        sysRole.setUpdatedAt(new Date());
        sysRole.setUpdaterId(loginInfoId);

        sysAgentRoleMapper.updateByPrimaryKeySelective(sysRole);

        //删除之前权限
        sysAgentRoleResourceMapper.deleteByRoleId(sysRoleUpdateReq.getId());
        //添加权限
        List<SysAgentRoleResource> sysRoleResourceList = new ArrayList<>();
        for (Long resourceId : sysRoleUpdateReq.getResourceList()) {
            SysAgentRoleResource sysRoleResource = new SysAgentRoleResource();
            sysRoleResource.setResourceId(resourceId);
            sysRoleResource.setRoleId(sysRoleUpdateReq.getId());
            sysRoleResource.setCreatedAt(new Date());
            sysRoleResourceList.add(sysRoleResource);
        }
        sysAgentRoleResourceMapper.insertRoleResouceList(sysRoleResourceList);
        //代理商需要对比子账号权限是否有变动
        if ("admin".equals(type)){
            List<SysAgentRoleResource> sysResourceList = new ArrayList<>();
            List<Long> longs = sysAgentRoleAccountMapper.selectLoginIdByRoleId(sysRoleUpdateReq.getId());
            for (Long l:longs) {
                SysAgentLoginInfo sysAgentLoginInfo = sysAgentLoginInfoMapper.selectByPrimaryKey(l);
                if (!ObjectUtils.isEmpty(sysAgentLoginInfo)){
                    List<Long> roleList = sysAgentRoleMapper.selectIdByAgentId(sysAgentLoginInfo.getAgentInfoId());
                    for (Long ls:roleList) {
                        List<Long> resourceList = sysAgentRoleResourceMapper.selectByRoleId(ls);
                        resourceList.retainAll(sysRoleUpdateReq.getResourceList());
                        for (Long resourceId:resourceList) {
                            SysAgentRoleResource sysRoleResource = new SysAgentRoleResource();
                            sysRoleResource.setResourceId(resourceId);
                            sysRoleResource.setRoleId(ls);
                            sysRoleResource.setCreatedAt(new Date());
                            sysResourceList.add(sysRoleResource);
                        }
                        sysAgentRoleResourceMapper.deleteByRoleId(ls);
                    }
                }
            }
            if (sysResourceList.size()>0){
                sysAgentRoleResourceMapper.insertRoleResouceList(sysResourceList);
            }

        }
        return ResponseData.success();
    }

    @Override
    public ResponseData delSysRole(DelReq delReq, Long loginInfoId, String type) throws Exception {
        if ("agent".equals(type)){
            SysAgentLoginInfo loginInfo = sysAgentLoginInfoMapper.selectByPrimaryKey(loginInfoId);
            if (StringUtils.isEmpty(loginInfo)) {
                return ResponseData.fail("未查询到此帐号");
            }
            List<Long> resps = sysAgentRoleMapper.selectLongList(loginInfo.getAgentInfoId());
            if (ObjectUtils.isEmpty(resps) || !resps.contains(delReq.getId())){
                return ResponseData.fail("未查询到此角色");
            }
        }

        //关联帐号不能删除
        int i = sysAgentRoleAccountMapper.selectByRoleId(delReq.getId());
        if (i > 0) {
            return ResponseData.fail("此角色已关联帐号");
        }
        SysAgentRole sysRole = new SysAgentRole();
        sysRole.setId(delReq.getId());
        sysRole.setIsDeleted((byte) 1);
        sysRole.setUpdaterId(loginInfoId);
        sysRole.setUpdatedAt(new Date());
        sysAgentRoleMapper.updateByPrimaryKeySelective(sysRole);
        return ResponseData.success();
    }

    @Override
    public ResponseData getResources(Long roleId, Long loginInfoId) throws Exception {
        List<SysAgentResource> list = null;
        if (!StringUtil.isNullorEmpty(roleId)) {
            list = sysAgentResourceMapper.selectRoleResourceList(roleId);
        }
        List<SysAgentResourceRoleResp> allList = new ArrayList<>();
        if (StringUtils.isEmpty(loginInfoId)){
            allList = sysAgentResourceMapper.selectAllResource();
        }else {
            SysAgentLoginInfo sysAgentLoginInfo = sysAgentLoginInfoMapper.selectByPrimaryKey(loginInfoId);
            if(ObjectUtils.isEmpty(sysAgentLoginInfo)){
                return ResponseData.fail(CodeIdEnum.NOLOGINACCOUNT);
            }
            List<Long> longs = sysAgentLoginInfoMapper.selectLoginId(sysAgentLoginInfo.getAgentInfoId());
            List<List<Long>> longList = new ArrayList<>();
            for (Long ls:longs) {
                longList.add(sysAgentResourceMapper.selectResourceList(ls));
            }
            for (int i = 0; i < longList.size(); i++) {
                if (i == 0){
                    continue;
                }
                longList.get(0).removeAll(longList.get(i));
                longList.get(0).addAll(longList.get(i));
            }
            for (Long l:longList.get(0)) {
               allList.add(sysAgentResourceMapper.selectAllResourceByLoginId(l));
            }

        }

        if (null != list && list.size() > 0 && null != allList && allList.size() > 0) {
            for (SysAgentResourceRoleResp roleResp : allList) {
                boolean show = false;
                for (SysAgentResource sysResource : list) {
                    if (sysResource.getId().equals(roleResp.getId())) {
                        show = true;
                    }
                }
                if (show) {
                    roleResp.setShow(1);
                }
            }
        }
        return ResponseData.success(allList);
    }

    @Override
    public ResponseData<SysRoleDetailResp> getRoleDetail(Long roleId) throws Exception {
        return ResponseData.success(sysAgentRoleMapper.selectByRoleId(roleId));
    }

    @Override
    public ResponseData selectList(Long loginInfoId) throws Exception {
        SysAgentLoginInfo info = sysAgentLoginInfoMapper.selectAgentId(loginInfoId);
        if (StringUtils.isEmpty(info)) {
            return ResponseData.fail("未查询到此帐号代理商");
        }
        return ResponseData.success(sysAgentRoleMapper.selectChooseList(info.getAgentInfoId()));
    }

    @Override
    public ResponseData selectAdminList() throws Exception {
        return ResponseData.success(sysAgentRoleMapper.selectChooseList((long) 0));
    }

    @Override
    public SysAgentRole selectById(Long id) {
        return sysAgentRoleMapper.selectByPrimaryKey(id);
    }
}
